package adhoc.tel.fer.hr;

import java.util.LinkedList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Handles lists of all friends, friends nearby, friends of friends
 * and friends of friends of friends.
 */
public class MyFriends extends ListActivity implements
		AdapterView.OnItemSelectedListener {
	
	private TextView selection;
	
	/** Options that can be used by user.*/
	private String[] deepness = { "All Friends", "Friends Nearby", "Friends of Friends", "Friends of Friends of Friends" };
	
	/** List of friends IDs.*/
	private List<String> friendIds;
	
	/** List of friends names.*/
	private List<String> friendNames;
	
	private static final String PREFS_NAME_IGNORED = "ignored.pref";
	private SharedPreferences ignoredPref;
	
	/** User ID fetched from Facebook.*/
	private String id;
	
	/** Selected friends list.*/
	private int selectedOption;
	
	/** Shows friends list options.*/
	private Spinner spin;
	
	/** Set layout and list content.*/
	private ArrayAdapter<String> listAdapter;
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		// TODO Auto-generated method stub
		super.onConfigurationChanged(newConfig);
    	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);    
	}
	
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.my_friend_background);
		selection = (TextView) findViewById(R.id.selection);

		spin = (Spinner) findViewById(R.id.spinner);
		spin.setOnItemSelectedListener(this);
		
		ArrayAdapter<String> aa = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, deepness);

		aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spin.setAdapter(aa);
		
		ignoredPref = getSharedPreferences(PREFS_NAME_IGNORED, 0);
		
		// Fetch user ID
		id = PreferencesHelper.getFacebookID();
	}

	public void onListItemClick(ListView parent, final View v, final int position, long id) {
		selection.setText(friendIds.get(position));
		
		// User on AllFriends list is selected, show ignore dialog 
		if (selectedOption == 0){
			AlertDialog alert = createDialog(position);
			alert.show();
		}
		
		// User on FriendsNearby list is selected, show ignore dialog
		else if (selectedOption == 1){
			AlertDialog alert = createDialog(position);
			alert.show();
		}
		
		// User on friends of friends or friends of friends of friends is selected,
		// show add dialog
		else if (selectedOption == 2 || selectedOption == 3){
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Add " + friendNames.get(position) + " as your friend?")
			       .setCancelable(false)
			       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			        	   new SendOverNetwork().execute(Config.WEB_SERVICE_URL+"/graph?fb_id=" + 
			        			   MyFriends.this.id + "&&fr_fb_id=" + friendIds.get(position) + "&&method=addFriend", "noResponse");
			        	   
			        	   Toast.makeText(selection.getContext(), "Added friend " + friendIds.get(position), Toast.LENGTH_SHORT).show();
			           }
			       })
			       .setNegativeButton("No", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			                dialog.cancel();
			           }
			       });
			
			AlertDialog alert = builder.create();
			alert.show();
		}
	}
	
	
	@Override
	public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
	
		// Sppiner listener!
		
		// Get AllFriends list
		if (position == 0){
			selectedOption = position;
			new SendOverNetwork().execute(Config.WEB_SERVICE_URL+"/graph?method=getFriendsAll&&fb_id=" + 
											this.id, "response");
		}
		
		// Get FriendsNearby list
		else if (position == 1){
			selectedOption = position;
			new SendOverNetwork().execute(Config.WEB_SERVICE_URL+"/graph?method=getFriendsNearby&&fb_id=" + 
											this.id, "response");
		}
		
		// Get FoF list
		else if (position == 2) {
			selectedOption = position;
			new SendOverNetwork().execute(Config.WEB_SERVICE_URL+"/graph?fb_id=" + this.id + "&&deepness=" + 
											(position), "response");
		}
		
		// Get FoFoF list
		else if (position == 3) {
			selectedOption = position;
			new SendOverNetwork().execute(Config.WEB_SERVICE_URL+"/graph?fb_id=" + this.id + "&&deepness=" + 
											(position), "response");
		}
			
	}

	@Override
	public void onNothingSelected(AdapterView<?> parent) {
		selection.setText("");
	}

	/**
	 * Send request to main server asynchronously.
	 */
	public class SendOverNetwork extends AsyncTask<String, String, JSONObject> {

		private ProgressDialog progress;
		
		@Override
		protected void onPreExecute() {
			progress = new ProgressDialog(selection.getContext());
			progress.setMessage("Communication with server. Please wait...");
			progress.show();
		}
		
		@Override
		protected JSONObject doInBackground(String... params) {
			JSONObject json = null;
			
			String url = params[0];
			String method = params[1];
			
			json = Util.makeGetRequest(url);
			
			// if request will get response
			if (method.equals("response")){
				try {
					friendNames = new LinkedList<String>();
					friendIds = new LinkedList<String>();
					
					JSONArray array = json.getJSONArray("data");
					String id = null;
					String name = null;
					for (int i = 0; i < array.length(); i++){
						JSONObject o = array.getJSONObject(i);
						id = o.getString("id");
						name = o.getString("name");
						System.out.println("Primljeno " + name);
						friendIds.add(id);
						friendNames.add(name);
					}
				}
				
				catch (JSONException e) {
					try {
						String error = json.getString("error");
						publishProgress(error);
					} catch (JSONException e1) {}
					
					e.printStackTrace();
				}
				catch (NullPointerException e) {
					publishProgress("No friends");
					e.printStackTrace();
				}
				publishProgress("over");	
			}
			progress.cancel();
			return json;
		} 
			
		@Override
		protected void onProgressUpdate(String... values) {
			
			if (values[0].equals("over")){
				listAdapter = new ArrayAdapter<String>(
						MyFriends.this.getBaseContext(), R.layout.new_friend_row,
						R.id.add_label, (String[]) friendNames.toArray(new String[0]));
				setListAdapter(listAdapter);
			}
			else {
				selection.setText(values[0]);
			}
		}
	}
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.my_friends_menu, menu);

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		switch (item.getItemId()) {

		case R.id.ign_list:
			Intent showIgnoredList = new Intent(this, IgnoreList.class);
			startActivity(showIgnoredList);
			break;
	}
		return true;
	}
	
	/**
	 * Save ignored friends in shared prefs.
	 * @param id Ignored friend ID.
	 * @param name Ignored friend name.
	 */
	private void putToIgnoredList(String id, String name){
		SharedPreferences.Editor editor = ignoredPref.edit();
		editor.putString(id, name);
		// Commit the edits!
		editor.commit();
	}
	
	/**
	 * Creates dialog for ignoring friend.
	 * @param position Index of ignored person in friends list.
	 * @return Alert ready to show.
	 */
	private AlertDialog createDialog(final int position){
		
		AlertDialog.Builder builder = new AlertDialog.Builder(MyFriends.this);
		builder.setMessage("Ignore " + friendNames.get(position) + "?")
		       .setCancelable(false)
		       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
						new SendOverNetwork().execute(Config.WEB_SERVICE_URL+"/graph?method=ignoreFriend&&fb_id=" + 
								MyFriends.this.id + "&&fr_fb_id=" + friendIds.get(position), "noResponse");
						putToIgnoredList(friendIds.get(position), friendNames.get(position));
		           }
		       })
		       .setNegativeButton("No", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		                dialog.cancel();
		           }
		       });
		
		AlertDialog alert = builder.create();
		
		return alert;
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
	
}